package com.autoagent.ai_live_master.scriptRecommendation.service.impl;

import com.autoagent.ai_live_master.common.utils.BeanConverter;
import com.autoagent.ai_live_master.scriptRecommendation.dto.LiveStreamingPlanDTO;
import com.autoagent.ai_live_master.scriptRecommendation.entity.LiveStreamingPlan;
import com.autoagent.ai_live_master.scriptRecommendation.mapper.LiveStreamingPlanMapper;
import com.autoagent.ai_live_master.scriptRecommendation.service.LiveStreamingPlanService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.time.LocalDateTime;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 直播计划服务实现类
 */
@Slf4j
@Service
public class LiveStreamingPlanServiceImpl extends ServiceImpl<LiveStreamingPlanMapper,LiveStreamingPlan> implements LiveStreamingPlanService {

    @Override
    public List<LiveStreamingPlanDTO> getAllLiveStreamingPlans(Long userId) {
        log.info("开始获取用户 {} 的直播计划列表", userId);
        try {
            LambdaQueryWrapper<LiveStreamingPlan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LiveStreamingPlan::getUserId, userId);

            List<LiveStreamingPlan> LiveStreamingPlans = this.list(queryWrapper);

            List<LiveStreamingPlanDTO> result = LiveStreamingPlans.stream()
                    .map(LiveStreamingPlan -> BeanConverter.convert(LiveStreamingPlan, LiveStreamingPlanDTO.class))
                    .collect(Collectors.toList());

            log.info("获取直播计划列表成功 - 数量: {}", result.size());
            return result;
        } catch (Exception e) {
            log.error("获取直播计划列表失败 - 错误信息: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public Page<LiveStreamingPlanDTO> getPageByUserId(Long userId, Integer pageNum, Integer pageSize) {
        log.info("分页获取用户的直播计划列表 - 用户ID: {}, 页码: {}, 每页大小: {}", userId, pageNum, pageSize);

        Page<LiveStreamingPlan> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<LiveStreamingPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LiveStreamingPlan::getUserId, userId);

        // 按创建时间倒序排列
        wrapper.orderByDesc(LiveStreamingPlan::getCreatedAt);

        Page<LiveStreamingPlan> entityPage = this.page(page, wrapper);

        // 转换为DTO分页对象
        Page<LiveStreamingPlanDTO> dtoPage = new Page<>();
        dtoPage.setTotal(entityPage.getTotal());
        dtoPage.setCurrent(entityPage.getCurrent());
        dtoPage.setSize(entityPage.getSize());
        dtoPage.setRecords(entityPage.getRecords().stream()
                .map(entity -> BeanConverter.convert(entity, LiveStreamingPlanDTO.class))
                .collect(Collectors.toList()));

        return dtoPage;
    }

    @Override
    public void createLiveStreamingPlan(LiveStreamingPlan LiveStreamingPlan) {
        log.info("开始创建直播计划 - 直播计划信息: {}", LiveStreamingPlan);
        try {
            // 保存新直播计划
            boolean success = this.save(LiveStreamingPlan);
            if (success) {
                log.info("直播计划创建成功 - id: {}", LiveStreamingPlan.getId());
            } else {
                log.error("直播计划创建失败");
                throw new RuntimeException("直播计划创建失败");
            }
        } catch (Exception e) {
            log.error("创建直播计划失败 - 错误信息: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public LiveStreamingPlanDTO updateLiveStreamingPlan(LiveStreamingPlan LiveStreamingPlan) {
        log.info("开始更新直播计划 - id: {}, 更新内容: {}", LiveStreamingPlan.getId(), LiveStreamingPlan);
        try {
            // 检查直播计划是否存在
            LiveStreamingPlan existingLiveStreamingPlan = this.getById(LiveStreamingPlan.getId());
            if (existingLiveStreamingPlan == null) {
                log.warn("更新直播计划失败 - 直播计划不存在, id: {}", LiveStreamingPlan.getId());
                return null;
            }
            // 直播计划存在，执行更新
            boolean success = this.updateById(LiveStreamingPlan);
            if (!success) {
                log.error("更新直播计划失败 - id: {}", LiveStreamingPlan.getId());
                throw new RuntimeException("更新直播计划失败");
            }
            // 重新获取更新后的直播计划信息
            LiveStreamingPlan updatedLiveStreamingPlan = this.getById(LiveStreamingPlan.getId());
            LiveStreamingPlanDTO result = BeanConverter.convert(updatedLiveStreamingPlan, LiveStreamingPlanDTO.class);
            log.info("更新直播计划成功 - id: {}", LiveStreamingPlan.getId());
            return result;
        } catch (Exception e) {
            log.error("更新直播计划失败 - id: {}, 错误信息: {}", LiveStreamingPlan.getId(), e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public boolean deleteLiveStreamingPlan(Integer id) {
        log.info("开始删除直播计划 - id: {}", id);
        try {
            // 检查直播计划是否存在
            LiveStreamingPlan existingLiveStreamingPlan = this.getById(id);
            if (existingLiveStreamingPlan == null) {
                log.warn("删除直播计划失败 - 直播计划不存在, id: {}", id);
                return false;
            }
            // 直播计划存在，执行删除
            boolean success = this.removeById(id);
            if (success) {
                log.info("删除直播计划成功 - id: {}", id);
            } else {
                log.error("删除直播计划失败 - id: {}", id);
                throw new RuntimeException("删除直播计划失败");
            }
            return true;
        } catch (Exception e) {
            log.error("删除直播计划失败 - id: {}, 错误信息: {}", id, e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public boolean enableLiveStreamingPlan(Integer id) {
        log.info("开始启用直播计划 - id: {}", id);
        try {
            // 检查直播计划是否存在
            LiveStreamingPlan existingLiveStreamingPlan = this.getById(id);
            if (existingLiveStreamingPlan == null) {
                log.warn("启用直播计划失败 - 直播计划不存在, id: {}", id);
                return false;
            }

            // 检查是否存在时间重叠的已启用直播计划
            Long userId = existingLiveStreamingPlan.getUserId();
            LocalDateTime startTime = existingLiveStreamingPlan.getStartTime();
            LocalDateTime endTime = existingLiveStreamingPlan.getEndTime();

            LambdaQueryWrapper<LiveStreamingPlan> conflictWrapper = new LambdaQueryWrapper<>();
            conflictWrapper.eq(LiveStreamingPlan::getUserId, userId)
                          .eq(LiveStreamingPlan::getEnabled, true)
                          .ne(LiveStreamingPlan::getId, id)  // 排除当前计划
                          // 时间重叠条件: (start1 < end2) && (start2 < end1)
                          .and(wrapper -> wrapper.lt(LiveStreamingPlan::getStartTime, endTime)
                                                .gt(LiveStreamingPlan::getEndTime, startTime));

            List<LiveStreamingPlan> conflictPlans = this.list(conflictWrapper);
            if (!conflictPlans.isEmpty()) {
                // 获取冲突计划的名称列表
                String conflictPlanNames = conflictPlans.stream()
                        .map(LiveStreamingPlan::getName)
                        .collect(Collectors.joining(", "));
                
                log.warn("启用直播计划失败 - 存在时间重叠的已启用直播计划, id: {}, 冲突计划名称: {}", id, conflictPlanNames);
                throw new RuntimeException("存在时间重叠的已启用直播计划 (名称: " + conflictPlanNames + "), 请先禁用或调整这些计划的时间");
            }

            // 直播计划存在且无时间冲突，执行启用
            existingLiveStreamingPlan.setEnabled(true);
            boolean success = this.updateById(existingLiveStreamingPlan);
            if (success) {
                log.info("启用直播计划成功 - id: {}", id);
            } else {
                log.error("启用直播计划失败 - id: {}", id);
                throw new RuntimeException("启用直播计划失败");
            }
            return true;
        } catch (Exception e) {
            log.error("启用直播计划失败 - id: {}, 错误信息: {}", id, e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public boolean disableLiveStreamingPlan(Integer id) {
        log.info("开始禁用直播计划 - id: {}", id);
        try {
            // 检查直播计划是否存在
            LiveStreamingPlan existingLiveStreamingPlan = this.getById(id);
            if (existingLiveStreamingPlan == null) {
                log.warn("禁用直播计划失败 - 直播计划不存在, id: {}", id);
                return false;
            }
            // 直播计划存在，执行禁用
            existingLiveStreamingPlan.setEnabled(false);
            boolean success = this.updateById(existingLiveStreamingPlan);
            if (success) {
                log.info("禁用直播计划成功 - id: {}", id);
            } else {
                log.error("禁用直播计划失败 - id: {}", id);
                throw new RuntimeException("禁用直播计划失败");
            }
            return true;
        } catch (Exception e) {
            log.error("禁用直播计划失败 - id: {}, 错误信息: {}", id, e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public LiveStreamingPlan findEnabledPlanByRoomId(String roomId) {
        log.info("根据房间ID查找启用的直播计划 - 房间ID: {}", roomId);
        try {
            LambdaQueryWrapper<LiveStreamingPlan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LiveStreamingPlan::getLiveRoomId, Long.valueOf(roomId))
                       .eq(LiveStreamingPlan::getEnabled, true)
                       .orderByDesc(LiveStreamingPlan::getCreatedAt); // 按创建时间倒序，取最新的

            List<LiveStreamingPlan> plans = this.list(queryWrapper);
            if (plans.isEmpty()) {
                log.warn("未找到启用的直播计划 - 房间ID: {}", roomId);
                return null;
            }

            // 返回第一个（最新的）启用的直播计划
            LiveStreamingPlan plan = plans.get(0);
            log.info("找到启用的直播计划 - 房间ID: {}, 计划ID: {}, 计划名称: {}", 
                    roomId, plan.getId(), plan.getName());
            return plan;
        } catch (NumberFormatException e) {
            log.error("房间ID格式错误 - 房间ID: {}, 错误信息: {}", roomId, e.getMessage());
            return null;
        } catch (Exception e) {
            log.error("查找直播计划失败 - 房间ID: {}, 错误信息: {}", roomId, e.getMessage(), e);
            return null;
        }
    }
}